home *** CD-ROM | disk | FTP | other *** search
/ Mac-Source 1994 July / Mac-Source_July_1994.iso / C and C++ / Libraries / GUSI / include / GUSI_P.h < prev    next >
Encoding:
C/C++ Source or Header  |  1993-08-10  |  10.2 KB  |  376 lines  |  [TEXT/MPS ]

  1. /*********************************************************************
  2. Project    :    GUSI                -    Grand Unified Socket Interface
  3. File        :    GUSI_P.h            -    Private stuff
  4. Author    :    Matthias Neeracher
  5. Started    :    24Mar92                                Language    :    MPW C/C++
  6. Modified    :    18Apr92    MN    ppc Domain
  7.                 18Apr92    MN    changed read/write/send/recv dispatchers
  8.                 19Apr92    MN    C++ rewrite
  9.                 21May92    MN    Implemented select()
  10.                 07Jun92    MN    Feature
  11.                 27Jun92    MN    choose(), hasNewSF
  12.                 13Jul92    MN    Make AppleTalkSockets global
  13.                 26Jul92    MN    UnixSockets.choose()
  14.                 30Jul92    MN    Initializer Features
  15.                 03Aug92    MN    RingBuffer
  16.                 30Aug92    MN    AppleTalkIdentity()
  17.                 13Sep92    MN    SPINVOID didn't return
  18.                 24Sep92    MN    Include GUSIRsrc_P.h
  19.                 03Jan93    MN    GUSIConfig
  20.                 17Jan93    MN    SAFESPIN
  21.                 17Jan93    MN    Destructors for Socketdomain
  22.                 31Jan93    MN    GUSIConfiguration::daemon
  23.                 09Feb93    MN    Socket::lurking, Socket::lurkdescr
  24.                 27Jun93    MN    Socket::ftruncate
  25.                 27Jun93    MN    Socket::{pre,post}_select
  26.                 17Jul93    MN    GUSIO_MAX_DOMAIN -> AF_MAX
  27.                 17Jul93    MN    GUSIRingBuffer::proc -> defproc
  28. Last        :    17Jul93
  29. *********************************************************************/
  30.  
  31. #include <GUSI.h>
  32. #include <GUSIRsrc_P.h>
  33. #include <TFileSpec.h>
  34.  
  35. extern "C" {
  36.  
  37. #include <sys/errno.h>
  38. #include <sys/uio.h>
  39. #include <sys/socket.h>
  40. #include <fcntl.h>
  41. #include <stdio.h>
  42. #include <string.h>
  43. #include <assert.h>
  44.  
  45. #include <Memory.h>
  46. #include <GestaltEqu.h>
  47. #include <Traps.h>
  48. #include <AppleEvents.h>
  49.  
  50. int         GUSI_error(int err);
  51. void *    GUSI_error_nil(int err);
  52. }
  53.  
  54. #pragma segment GUSI
  55.  
  56. #define GUSI_MAX_DOMAIN            AF_MAX
  57. #define DEFAULT_BUFFER_SIZE    4096
  58.  
  59. /*
  60.  *    In use and shutdown status.
  61.  */
  62. #define    SOCK_STATUS_USED        0x1        /* Used socket table entry */
  63. #define    SOCK_STATUS_NOREAD    0x2        /* No more reading allowed from socket */
  64. #define    SOCK_STATUS_NOWRITE    0x4        /* No more writing allowed to socket */
  65.  
  66. /*
  67.  *    Socket connection states.
  68.  */
  69. #define    SOCK_STATE_NO_STREAM        0    /* Socket doesn't have a MacTCP stream yet */
  70. #define    SOCK_STATE_UNCONNECTED    1    /* Socket is unconnected. */
  71. #define    SOCK_STATE_LISTENING        2    /* Socket is listening for connection. */
  72. #define    SOCK_STATE_LIS_CON        3    /* Socket is in transition from listen to connected. */
  73. #define    SOCK_STATE_CONNECTING    4    /* Socket is initiating a connection. */
  74. #define    SOCK_STATE_CONNECTED        5    /* Socket is connected. */
  75. #define    SOCK_STATE_CLOSING      6    /* Socket is closing */
  76.  
  77. #define        min(a,b)                ( (a) < (b) ? (a) : (b))
  78. #define        max(a,b)                ( (a) > (b) ? (a) : (b))
  79.  
  80. extern GUSISpinFn GUSISpin;
  81. extern "C" int GUSIDefaultSpin(spin_msg, long);
  82.  
  83. /* SPIN returns a -1 on user cancel for fn returning integers */
  84. #define        SPIN(cond,mesg,param)                            \
  85.                     do {                                                \
  86.                         if (GUSISpin)                            \
  87.                             if ((*GUSISpin)(mesg,param))    \
  88.                                 return GUSI_error(EINTR);        \
  89.                     } while(cond)
  90.  
  91. /* SPINP returns a NULL on user cancel, for fn returning pointers */                
  92. #define        SPINP(cond,mesg,param)                            \
  93.                     do {                                                \
  94.                         if (GUSISpin)                            \
  95.                             if ((*GUSISpin)(mesg,param)) {\
  96.                                 GUSI_error(EINTR);                \
  97.                                 return NULL;                        \
  98.                             }                                            \
  99.                     } while(cond)
  100.  
  101. /* SPINVOID just returns on user cancel, for fn returning void */                
  102. #define        SPINVOID(cond,mesg,param)                        \
  103.                     do {                                                \
  104.                         if (GUSISpin)                                \
  105.                             if ((*GUSISpin)(mesg,param)) {    \
  106.                                 GUSI_error(EINTR);                \
  107.                                 return;                                \
  108.                             }                                            \
  109.                     } while(cond)
  110.                     
  111. /* SAFESPIN doesn't return, you have to check errno */                
  112. #define        SAFESPIN(cond,mesg,param)                        \
  113.                     do {                                                \
  114.                         if (GUSISpin)                                \
  115.                             if ((*GUSISpin)(mesg,param)) {    \
  116.                                 GUSI_error(EINTR);                \
  117.                                 break;                                \
  118.                             } else {                                    \
  119.                                 errno = 0;                            \
  120.                             }                                            \
  121.                         else                                            \
  122.                             errno = 0;                                \
  123.                     } while(cond)
  124.                     
  125. class SocketTable;
  126.  
  127. class Socket {
  128.     friend class SocketTable;
  129.     
  130.     short            refCount;
  131. protected:
  132.     Boolean        lurking;
  133.     char            lurkDescr;
  134.     
  135.                     Socket();
  136. public:
  137.     virtual int    bind(void * name, int namelen);
  138.     virtual int connect(void * address, int addrlen);
  139.     virtual int listen(int qlen);
  140.     virtual Socket * accept(void * address, int * addrlen);
  141.     virtual int    read(void * buffer, int buflen);
  142.     virtual int write(void * buffer, int buflen);
  143.     virtual int recvfrom(void * buffer, int buflen, int flags, void * from, int * fromlen);
  144.     virtual int sendto(void * buffer, int buflen, int flags, void * to, int tolen);
  145.     virtual int getsockname(void * name, int * namelen);
  146.     virtual int getpeername(void * name, int * namelen);
  147.     virtual int getsockopt(int level, int optname, void *optval, int * optlen);
  148.     virtual int setsockopt(int level, int optname, void *optval, int optlen);
  149.     virtual int    fcntl(unsigned int cmd, int arg);
  150.     virtual int    ioctl(unsigned int request, void *argp);
  151.     virtual int    fstat(struct stat * buf);
  152.     virtual long lseek(long offset, int whence);
  153.     virtual int ftruncate(long offset);
  154.     virtual int    isatty();
  155.     virtual int shutdown(int how);
  156.     virtual void pre_select(Boolean wantRead, Boolean wantWrite, Boolean wantExcept);
  157.     virtual int select(Boolean * canRead, Boolean * canWrite, Boolean * exception);
  158.     virtual void post_select(Boolean wantRead, Boolean wantWrite, Boolean wantExcept);
  159.     virtual         ~Socket();
  160. };
  161.  
  162. class SocketDomain {
  163.     static SocketDomain *    domains[GUSI_MAX_DOMAIN];
  164. protected:
  165.     SocketDomain(int domain);
  166.     virtual ~SocketDomain();
  167. public:
  168.     inline static SocketDomain *    Domain(int domain);
  169.     
  170.     // Override *one* of the following two
  171.     
  172.     virtual Socket * open(const char * filename, int oflag);
  173.     virtual Socket * socket(int type, short protocol);
  174.     
  175.     // Optionally define the following
  176.     
  177.     virtual int choose(
  178.                         int         type, 
  179.                         char *     prompt, 
  180.                         void *     constraint,        
  181.                         int         flags,
  182.                          void *     name, 
  183.                         int *     namelen);
  184.     
  185.     // Never override the following
  186.     
  187.     virtual void DontStrip();
  188. };
  189.  
  190. class DeviceSocketDomain : public SocketDomain {
  191. protected:
  192.     friend class FileSocketDomain;
  193.     
  194.     static DeviceSocketDomain *    firstDev;
  195.     static const Socket *            TryNextDevice;
  196.     DeviceSocketDomain *                nextDev;
  197.  
  198.     DeviceSocketDomain(int domain);
  199. };
  200.  
  201. class SocketTable {
  202.     Socket *    sockets[GUSI_MAX_FD];
  203. public:
  204.     SocketTable();
  205.     ~SocketTable();
  206.     
  207.     int        Install(Socket * sock, int start = 0);
  208.     int        Remove(int fd);
  209.     Socket * operator[](int fd);
  210.     
  211.     void        Possess(int descr, Socket * sock);    // Install a daemon
  212. };
  213.  
  214. class FileSocketDomain : public SocketDomain {
  215.     friend SocketTable::SocketTable();
  216.     
  217.     virtual Socket * stdopen(int fd);
  218. public:
  219.     FileSocketDomain()    :    SocketDomain(AF_FILE)    {    }
  220.  
  221.     virtual Socket * open(const char * filename, int oflag);
  222.     virtual int choose(
  223.                         int         type, 
  224.                         char *     prompt, 
  225.                         void *     constraint,        
  226.                         int         flags,
  227.                          void *     name, 
  228.                         int *     namelen);
  229. };
  230.  
  231. struct GUSISuffix {
  232.     char         suffix[4];
  233.     OSType    suffType;
  234.     OSType    suffCreator;
  235. };
  236.  
  237. struct GUSIConfiguration {
  238.     OSType            defaultType;
  239.     OSType            defaultCreator;
  240.     
  241.     char                autoSpin;
  242.     
  243.     unsigned         noChdir         : 1;    // Set current directory without chdir()
  244.     unsigned         accurStat    : 1;    // Return # of subdirectories + 2 in st_nlink
  245.     unsigned         tcpDaemon    : 1;    // Works as a TCP daemon ?
  246.     unsigned         udpDaemon    : 1;    // Works as an UDP daemon ?
  247.     unsigned         filler2        : 4;
  248.     
  249.     OSType            version;
  250.     short                numSuffices;
  251.     GUSISuffix *    suffices;
  252.     
  253.     GUSIConfiguration();
  254.     
  255.     void SetDefaultFType(const TFileSpec & name) const;
  256.     void DoAutoSpin() const;
  257.     Boolean IsDaemon() const;
  258. private:
  259.     static Boolean firstTime;
  260.     static short    we;
  261. };
  262.  
  263. extern const GUSIConfiguration    GUSIConfig;
  264. extern SocketTable                    Sockets;
  265. extern FileSocketDomain             FileSockets;
  266.  
  267. typedef pascal OSErr (*OSErrInitializer)();
  268. typedef pascal void  (*voidInitializer)();
  269.  
  270. class Feature {
  271.     Boolean    good;
  272. public:
  273.     Feature(short trapNum, TrapType tTyp);
  274.     Feature(OSType type, long value);
  275.     Feature(OSType type, long mask, long value);
  276.     Feature(const Feature & precondition, OSErrInitializer init);
  277.     Feature(OSErrInitializer init);
  278.     Feature(const Feature & precondition, voidInitializer init);
  279.     Feature(voidInitializer init);
  280.     Feature(const Feature & cond1, const Feature & cond2);
  281.  
  282.     operator void*() const {    return (void *) good;    }
  283. };
  284.  
  285. extern Feature hasMakeFSSpec;
  286. extern Feature hasAlias;
  287. extern Feature    hasWNE;
  288. extern Feature hasNewSF;
  289. extern Feature hasProcessMgr;
  290. extern Feature hasCRM;
  291. extern Feature hasCTB;
  292. extern Feature hasStdNBP;
  293. extern Feature hasCM;
  294. extern Feature hasFT;
  295. extern Feature hasTM;
  296. extern Feature    hasPPC;
  297. extern Feature hasRevisedTimeMgr;
  298.  
  299. class ScattGath    {
  300.     Handle            scratch;
  301. protected:
  302.     void *            buf;
  303.     int                        len;
  304.     int                        count;
  305.     const struct iovec *    io;
  306.  
  307.     ScattGath(const struct iovec *iov, int cnt);
  308.     virtual ~ScattGath();
  309. public:
  310.     void *            buffer()            {    return buf;            }
  311.     int                buflen()            {    return len;            }
  312.     int                length(int l)    {    return len = l;    }
  313.     operator void *()                    {    return buf;            }
  314. };
  315.  
  316. class Scatterer : public ScattGath {
  317. public:
  318.     Scatterer(const struct iovec *iov, int count);
  319.     virtual ~Scatterer();
  320. };
  321.  
  322. class Gatherer : public ScattGath {
  323. public:
  324.     Gatherer(const struct iovec *iov, int count);
  325.     virtual ~Gatherer();
  326. };
  327.  
  328. typedef pascal void (*Deferred)(void *);
  329.  
  330. class RingBuffer {
  331.     // Valid bytes are between consume and produce
  332.     // Free bytes are between produce and consume
  333.     // bytes between endbuf-spare and endbuf are neither
  334.     Ptr        buffer;
  335.     Ptr        endbuf;
  336.     Ptr         consume;
  337.     Ptr        produce;
  338.     u_short    free;
  339.     u_short    valid;
  340.     u_short    spare;
  341.     Boolean    lock;
  342.     Deferred    defproc;
  343.     void *    arg;
  344.     
  345. public:
  346.                 RingBuffer(u_short bufsiz);
  347.                 ~RingBuffer();
  348.     
  349.     Ptr        Producer(long & len);            //    Find continuous memory for producer
  350.     Ptr        Consumer(long & len);            //    Find continuous memory for consumer
  351.     void        Validate(long len);                // Validate this, unallocate rest
  352.     void         Invalidate(long len);
  353.     void        Produce(Ptr from, long & len);//    Allocate, copy & validate
  354.     void        Consume(Ptr to, long & len);    // Copy & invalidate
  355.     
  356.     long        Free()                                { return free;                                    }        
  357.     long        Valid()                                { return valid;                                }
  358.     
  359.     void         Defer()                                { lock = true;                                    }
  360.     void         Undefer()                            { lock = false; if (defproc) defproc(arg);}
  361.     Boolean    Locked()                                { return lock;                                    }
  362.     void        Later(Deferred def, void * ar){ defproc = def; arg = ar;                    }
  363.     
  364.     operator void *()                                { return buffer;                                }
  365. };
  366.  
  367. Boolean GUSIInterrupt();
  368.  
  369. Boolean CopyIconFamily(short srcResFile, short srcID, short dstResFile, short dstID);
  370.  
  371. pascal OSErr PPCInit_P();
  372.  
  373. OSErr AppleTalkIdentity(short & net, short & node);
  374.  
  375. pascal OSErr GetOffMyCloud(AppleEvent*, AppleEvent*, long); // We don't want this aevt
  376.